<!-- RolePermissionTree.vue -->
<template>
  <div class="role-permission-tree">
    <el-tree
      ref="permissionTree"
      :data="treeData"
      show-checkbox
      node-key="id"
      :default-checked-keys="defaultCheckedKeys"
      :default-expanded-keys="defaultExpandedKeys"
      :props="treeProps"
      @check="handleCheckChange"
      highlight-current
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <span>{{ data.label }}</span>
        </span>
      </template>
    </el-tree>
  </div>
</template>

<script>
import { MenuData } from '@/public/engine/menus/menuData'
import { PermissionInfo } from '@/public/engine/menus/permissionInfo'

export default {
  name: 'RolePermissionTree',
  
  props: {
    // Current role's permissions PermissionInfo
    initPermission: {
      type: PermissionInfo,
      default: null
    },
    // Menu tree data  MenuData
    menuTree: {
      type: Array,
      default: () => []
    },
    // Control whether nodes are expanded by default
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    // Specific keys to expand by default (alternative to expanding all)
    defaultExpandedKeys: {
      type: Array,
      default: () => []
    }
  },

  data() {
    return {
      rolePermissions: [],  //List<String> permissionCodeList = [];
      treeData: [],
      defaultCheckedKeys: [],
      treeProps: {
        children: 'children',
        label: 'label',
        disabled: 'disabled'
      }
    }
  },

  computed: {
    // Computed property to determine which keys should be expanded
    computedExpandedKeys() {
      // If specific keys are provided, use them
      if (this.defaultExpandedKeys && this.defaultExpandedKeys.length > 0) {
        return this.defaultExpandedKeys;
      }
      
      // If defaultExpandAll is true, expand all nodes
      if (this.defaultExpandAll) {
        return this.getAllNodeKeys(this.treeData);
      }
      
      // Otherwise, return empty array (all collapsed)
      return [];
    }
  },

  watch: {
    initPermission: {
      handler() {
       // console.log('initPermission watch:', this.initPermission)
        this.rolePermissions = this.initPermission?.getLeafTreeNode() ?? [];
        this.initCheckedKeys()
      },
      immediate: true
    },
    menuTree: {
      handler() {
        this.initTreeData()
      },
      immediate: true
    }
  },

  mounted() {
    //console.log('initPermission mounted:', this.initPermission)
    this.rolePermissions = this.initPermission?.getLeafTreeNode() ?? [];
    this.initTreeData()
    this.initCheckedKeys()
  },

  methods: {
    // Convert menu tree to tree component data structure
    initTreeData() {
      this.treeData = this.convertMenuTree(this.menuTree)
    },

    // Convert MenuData structure to Element Plus tree structure
    convertMenuTree(menuList, parentId = '') {
      if (!menuList || menuList.length === 0) return []

      return menuList.map((menu, index) => {
        const nodeId = parentId ? `${parentId}-${index}` : `${index}`
        const node = {
          id: nodeId,
          code: menu.code,
          label: menu.name,
          funCode: menu.funCode,
          permissionList: menu.permissionList || [],
          children: []
        }

        // Add permissions as children
        if (menu.permissionList && menu.permissionList.length > 0) {
          node.children = menu.permissionList.map((perm, permIndex) => ({
            id: `${nodeId}-p${permIndex}`,
            code: perm.code,
            label: perm.name,
            isPermission: true
          }))
        }

        // Add submenu as children
        if (menu.subMenuList && menu.subMenuList.length > 0) {
          const subMenuChildren = this.convertMenuTree(menu.subMenuList, nodeId)
          node.children = [...node.children, ...subMenuChildren]
        }

        return node
      })
    },

    // Get all node keys for default expansion
    getAllNodeKeys(treeData) {
      const keys = []
      
      const traverse = (nodes) => {
        nodes.forEach(node => {
          keys.push(node.id)
          if (node.children && node.children.length > 0) {
            traverse(node.children)
          }
        })
      }
      
      traverse(treeData)
      return keys
    },

    // Initialize checked keys based on role permissions
    initCheckedKeys() {
      const checkedKeys = []
      
      const findMatchingNodes = (nodes) => {
        nodes.forEach(node => {
          // Check if node code matches role permissions
          if (this.rolePermissions.includes(node.code) || 
              (node.funCode && this.rolePermissions.includes(node.funCode))) {
            checkedKeys.push(node.id)
          }
          
          // Check if any permissionList item matches
          if (node.permissionList && node.permissionList.length > 0) {
            node.permissionList.forEach(perm => {
              if (this.rolePermissions.includes(perm.code)) {
                // Find the corresponding tree node
                const permNode = this.findNodeByCode(node.children, perm.code)
                if (permNode) {
                  checkedKeys.push(permNode.id)
                }
              }
            })
          }
          
          // Recursively check children
          if (node.children && node.children.length > 0) {
            findMatchingNodes(node.children)
          }
        })
      }
      
      findMatchingNodes(this.treeData)
      this.defaultCheckedKeys = checkedKeys
    },

    // Find node by code
    findNodeByCode(nodes, code) {
      if (!nodes || nodes.length === 0) return null
      
      for (const node of nodes) {
        if (node.code === code) {
          return node
        }
        if (node.children && node.children.length > 0) {
          const found = this.findNodeByCode(node.children, code)
          if (found) return found
        }
      }
      return null
    },

    // Handle tree check change
    handleCheckChange(data, checkedInfo) {
      const { checkedNodes, checkedKeys } = checkedInfo
      const permissions = this.extractPermissions(checkedNodes)
      this.$emit('permission-change', permissions)
    },

    // Extract permissions from checked nodes
    extractPermissions(checkedNodes) {
      const permissions = []
      
      const traverse = (nodes) => {
        nodes.forEach(node => {
          // Add node code if it's a menu or function
          if (node.code) {
            permissions.push(node.code)
          }
          
          // Add funCode if exists
          if (node.funCode) {
            permissions.push(node.funCode)
          }
          
          // Add permission codes
          if (node.isPermission && node.code) {
            permissions.push(node.code)
          }
          
          // Traverse children
          if (node.children && node.children.length > 0) {
            traverse(node.children)
          }
        })
      }
      
      traverse(checkedNodes)
      return [...new Set(permissions)] // Remove duplicates
    },

    // Get all checked permissions
    getCheckedPermissions() {
      const checkedNodes = this.$refs.permissionTree.getCheckedNodes(false, true)
      return this.extractPermissions(checkedNodes)
    },

    // Set checked permissions
    setCheckedPermissions(permissions) {
      this.$nextTick(() => {
        // Clear all checked
        this.$refs.permissionTree.setCheckedKeys([])
        
        // Find and check nodes that match permissions
        const allNodes = this.getAllNodes(this.treeData)
        const keysToCheck = []
        
        allNodes.forEach(node => {
          if (permissions.includes(node.code) || 
              (node.funCode && permissions.includes(node.funCode)) ||
              (node.isPermission && permissions.includes(node.code))) {
            keysToCheck.push(node.id)
          }
        })
        
        this.$refs.permissionTree.setCheckedKeys(keysToCheck)
      })
    },

    // Get all nodes in the tree
    getAllNodes(treeData) {
      const nodes = []
      
      const traverse = (data) => {
        data.forEach(node => {
          nodes.push(node)
          if (node.children && node.children.length > 0) {
            traverse(node.children)
          }
        })
      }
      
      traverse(treeData)
      return nodes
    }
  }
}
</script>

<style scoped>
.role-permission-tree {
  padding: 20px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>